package net.paoding.rose.jade.statement.jexl.analysis.impl;

import net.paoding.rose.jade.constant.JadeConstant;
import net.paoding.rose.jade.statement.jexl.Jexl3Execute;
import net.paoding.rose.jade.statement.jexl.analysis.Analysis;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;

/**
 * for循环解析
 * @author fusheng.zhang
 * @date 2022-03-05 16:24:15
 */
public class ForAnalysis implements Analysis {

    /**
     * 变量名
     */
    private String variable;
    /**
     * 要遍历的数组/集合
     */
    private String forCondition;
    /**
     * 循环体语句;
     */
    private List<Analysis> forExecutes;

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        if (Objects.nonNull(forCondition)) {
            str.append("for ( ").append(variable).append(" in ").append(forCondition).append(" ){");
            if (Objects.nonNull(forExecutes)) {
                forExecutes.forEach(analysis -> str.append(analysis.toString()));
            }
            str.append("}");
        }
        return str.toString();
    }

    @Override
    public void execute(Jexl3Execute jexl3Execute) {
        Object oldValue = jexl3Execute.getParams().get(variable);
        Object execute = jexl3Execute.execute(jexl3Execute.getParams(), jexl3Execute.getConstantParams(), toStr(forCondition));
        asCollection(execute).stream()
                .peek(o -> jexl3Execute.setParam(JadeConstant.CONNECTION_INDEX_FLAG, jexl3Execute.getIndex()))
                .peek(o -> jexl3Execute.setIndex(jexl3Execute.getIndex() + 1))
                .peek(o -> jexl3Execute.setParam(variable, o))
                .forEach(o -> {
                    if (!CollectionUtils.isEmpty(forExecutes)) {
                        forExecutes.forEach(analysis -> analysis.execute(jexl3Execute));
                    }
                });
        jexl3Execute.setIndex(0);
        jexl3Execute.setParam(variable, oldValue);
    }

    public String getVariable() {
        return variable;
    }

    public void setVariable(String variable) {
        this.variable = variable;
    }

    public String getForCondition() {
        return forCondition;
    }

    public void setForCondition(String forCondition) {
        this.forCondition = forCondition;
    }

    public List<Analysis> getForExecutes() {
        return forExecutes;
    }

    public void setForExecutes(List<Analysis> forExecutes) {
        this.forExecutes = forExecutes;
    }
}
